<template>
  <div>
    <Card title="JWT令牌" class="w-1/2 !m-10px min-w-700px">
      <div class="flex items-center justify-between">
        <span>令牌有效期至：{{ exp }}</span>
        <Button type="primary" @click="copy">复制JWT令牌</Button>
      </div>
    </Card>
    <Card class="w-1/2 !m-10px min-w-700px">
      <div class="flex flex-row w-full">
        <div class="flex flex-col w-1/2">
          <span class="font-medium text-lg mb-16px">更改密码</span>
          <Form
            layout="vertical"
            :model="password"
            :requiredMark="false"
            ref="formRef"
            :rules="formRule"
          >
            <FormItem label="当前密码" name="currentPassword" required>
              <InputPassword
                v-model:value="password.currentPassword"
                placeholder="当前密码"
                @change="passwordChange"
                :allowClear="true"
              />
            </FormItem>
            <FormItem label="新密码" name="newPassword" required>
              <InputPassword
                v-model:value="password.newPassword"
                placeholder="新密码"
                @change="passwordChange"
                :allowClear="true"
              />
            </FormItem>
            <FormItem label="再次输入新密码" name="confirmPassword" required>
              <InputPassword
                v-model:value="password.confirmPassword"
                placeholder="再次输入新密码"
                @change="passwordChange"
                :allowClear="true"
              />
            </FormItem>
          </Form>
          <div class="flex justify-around mt-20px" v-if="isedit">
            <Button @click="abandon">放弃更改</Button>
            <Button type="primary" @click="save">更改密码</Button>
          </div>
        </div>
        <Divider type="vertical" class="!h-auto" />
        <div class="flex flex-col w-1/2">
          <span class="font-medium text-lg mb-16px">密码要求</span>
          <span class="ml-12px">至少：</span>
          <List itemLayout="vertical" :split="false" class="!ml-20px">
            <ListItem v-if="passwordRule?.minimumUppercaseLetters !== 0">
              <ListItemMeta>
                <template #title>
                  <span> {{ passwordRule?.minimumUppercaseLetters }}位大写字母 </span>
                </template>
                <template #avatar>
                  <Icon :icon="checks.uppercase ? 'openmoji:check-mark' : 'tabler:point-filled'" />
                </template>
              </ListItemMeta>
            </ListItem>
            <ListItem v-if="passwordRule?.minimumLowercaseLetters !== 0">
              <ListItemMeta>
                <template #title>
                  <span> {{ passwordRule?.minimumLowercaseLetters }}位小写字母 </span>
                </template>
                <template #avatar>
                  <Icon :icon="checks.lowercase ? 'openmoji:check-mark' : 'tabler:point-filled'" />
                </template>
              </ListItemMeta>
            </ListItem>
            <ListItem v-if="passwordRule?.minimumDigits !== 0">
              <ListItemMeta>
                <template #title>
                  <span> {{ passwordRule?.minimumDigits }}位数字 </span>
                </template>
                <template #avatar>
                  <Icon :icon="checks.digit ? 'openmoji:check-mark' : 'tabler:point-filled'" />
                </template>
              </ListItemMeta>
            </ListItem>
            <ListItem v-if="passwordRule?.minimumSpecialCharacters !== 0">
              <ListItemMeta>
                <template #title>
                  <span> {{ passwordRule?.minimumSpecialCharacters }}位特殊字符 </span>
                </template>
                <template #avatar>
                  <Icon :icon="checks.Special ? 'openmoji:check-mark' : 'tabler:point-filled'" />
                </template>
              </ListItemMeta>
            </ListItem>
            <ListItem v-if="passwordRule?.minimumLength !== 0">
              <ListItemMeta>
                <template #title>
                  <span> {{ passwordRule?.minimumLength }}位字符 </span>
                </template>
                <template #avatar>
                  <Icon :icon="checks.length ? 'openmoji:check-mark' : 'tabler:point-filled'" />
                </template>
              </ListItemMeta>
            </ListItem>
          </List>
        </div>
      </div>
    </Card>
  </div>
</template>
<script lang="ts" setup>
  import {
    Card,
    Button,
    Divider,
    Form,
    FormItem,
    InputPassword,
    List,
    ListItem,
    ListItemMeta,
  } from 'ant-design-vue';
  import Icon from '/@/components/Icon';
  import { onMounted, ref, onActivated } from 'vue';
  import jwt_decode from 'jwt-decode';
  import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { getPasswordPolicy, changePassword } from '/@/api/thingsborad/account/account';
  import type { Rule } from 'ant-design-vue/es/form';
  let JWTtoken = ref();
  //有效期时间至
  let exp = ref();
  //密码要求
  let passwordRule = ref<Recordable>({});
  const { clipboardRef } = useCopyToClipboard();
  const { createMessage } = useMessage();
  let password = ref<Recordable>({
    currentPassword: '',
    newPassword: '',
    confirmPassword: '',
  });
  let isedit = ref<boolean>(false);
  let formRef = ref<any>();
  let formRule: Record<string, Rule[]> = {
    newPassword: [{ validator: validatePass, trigger: 'blur' }],
    confirmPassword: [{ validator: validateconfirm, trigger: 'blur' }],
  };
  //校验状态
  let checks = ref<Recordable>({
    length: false,
    lowercase: false,
    uppercase: false,
    digit: false,
    Special: false,
  });
  onMounted(async () => {
    await getPasswordRule();
    let token: string | null = localStorage.getItem('jwt_token');
    JWTtoken.value = jwt_decode(token as string);

    let date = new Date(JWTtoken.value.exp * 1000);
    exp.value = date.toLocaleString();
  });

  onActivated(async () => {
    await getPasswordRule();
  });
  //获取密码要求
  async function getPasswordRule() {
    passwordRule.value = await getPasswordPolicy();
  }
  function copy() {
    try {
      clipboardRef.value = localStorage.getItem('jwt_token') as string;
      createMessage.success('复制成功');
    } catch (e) {
      createMessage.error('复制失败');
    }
  }

  function passwordChange() {
    isedit.value = true;
  }
  //重置校验的状态
  function resetChecks() {
    checks.value = {
      length: false,
      lowercase: false,
      uppercase: false,
      digit: false,
      Special: false,
    };
  }
  //验证新密码的格式
  function validatePass() {
    let hasFalse = false;
    if (passwordRule.value.minimumLength !== 0) {
      const regex = new RegExp(`^.{${passwordRule.value.minimumLength},}$`);
      checks.value.length = regex.test(password.value.newPassword);
      if (!checks.value.length) hasFalse = true;
    }
    if (passwordRule.value.minimumDigits !== 0) {
      const numericCharMatches = password.value.newPassword.match(/\d/g) || [];
      if (numericCharMatches.length >= passwordRule.value.minimumDigits) {
        checks.value.digit = true;
      } else {
        checks.value.digit = false;
        hasFalse = true;
      }
    }
    if (passwordRule.value.minimumLowercaseLetters !== 0) {
      const lowercaseCharMatches = password.value.newPassword.match(/[a-z]/g) || [];
      if (lowercaseCharMatches.length >= passwordRule.value.minimumLowercaseLetters) {
        checks.value.lowercase = true;
      } else {
        checks.value.lowercase = false;
        hasFalse = true;
      }
    }
    if (passwordRule.value.minimumUppercaseLetters !== 0) {
      const uppercaseMatches = password.value.newPassword.match(/[A-Z]/g) || [];
      if (uppercaseMatches.length >= passwordRule.value.minimumUppercaseLetters) {
        checks.value.uppercase = true;
      } else {
        checks.value.uppercase = false;
        hasFalse = true;
      }
    }
    if (passwordRule.value.minimumSpecialCharacters !== 0) {
      const specialCharMatches = password.value.newPassword.match(/[^a-zA-Z0-9]/g) || [];
      if (specialCharMatches.length >= passwordRule.value.minimumSpecialCharacters) {
        checks.value.Special = true;
      } else {
        checks.value.Special = false;
        hasFalse = true;
      }
    }

    if (hasFalse) {
      return Promise.reject(new Error('密码格式不正确'));
    } else {
      return Promise.resolve();
    }
  }
  //校验两次输入的密码
  function validateconfirm() {
    if (password.value.newPassword !== password.value.confirmPassword) {
      return Promise.reject(new Error('两次输入的密码不一致'));
    } else {
      return Promise.resolve();
    }
  }

  //放弃更改
  function abandon() {
    password.value = {
      currentPassword: '',
      newPassword: '',
      confirmPassword: '',
    };
    isedit.value = false;
    formRef.value.resetFields();
    resetChecks();
  }

  async function save() {
    await formRef.value.validate();
    try {
      await changePassword(password.value);
      createMessage.success('修改成功');
    } catch (e) {
      createMessage.error('修改失败');
    }

    formRef.value.resetFields();
    resetChecks();
  }
</script>
<style lang="less" scoped>
  .ant-list-item {
    padding: 0;
  }
  .ant-list-item-meta {
    align-items: center;
  }
  ::v-deep(.ant-list-item-meta-avatar) {
    margin-right: 8px;
  }
  ::v-deep(.ant-list-item-meta-title) {
    margin-bottom: 0px;
  }
</style>
